package com.lkr.webapp.web.control;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Strings;
import com.lkr.webapp.bean.*;
import com.lkr.webapp.util.Constant;
import com.lkr.webapp.util.IdUtils;
import com.lkr.webapp.util.ResultUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * room control
 *
 * @author lss
 * @date 2019-01-21, Mon
 */
@RestController
@RequestMapping("/api/foo")
public class FooController {


    /**
     * 房间信息作缓存
     */
    private static RedisTemplate<String, Foo> redisTemplate;

    /**
     * 房间成员缓存
     */
    private static RedisTemplate<String, List<FooMember>> redisTemplate2;

    private static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm");

    private final SimpMessagingTemplate messagingTemplate;


    @Autowired
    public void setRedisTemplate(RedisTemplate<String, Foo> redisTemplate) {
        FooController.redisTemplate = redisTemplate;
    }

    @Autowired
    public FooController(SimpMessagingTemplate messagingTemplate) {
        this.messagingTemplate = messagingTemplate;
    }

    @RequestMapping("/create")
    public Result fooCreate(@RequestBody Foo foo, HttpServletRequest request) throws JsonProcessingException {
        Result<Foo> result = new Result<>();
        String fooId = getDiffFooId();
        if (Strings.isNullOrEmpty(fooId)) {
            ResultUtils.packFailedResult(result, "当前房间拥挤，请稍后进行创建");
            return result;
        }
        foo.setId(fooId);
        foo.setState(FooState.CREATED);
        foo.setGmtCreated(format.format(new Date()));
        if (Strings.isNullOrEmpty(foo.getName())) {
            foo.setName("ROOM-" + fooId);
        }
        if (Strings.isNullOrEmpty(foo.getDescription())) {
            foo.setDescription("房主很懒，什么也没有写");
        }
        result.setData(foo);
        redisTemplate.opsForValue().set(fooId, foo, Constant.fooExpired);
        System.out.println(new ObjectMapper().writeValueAsString(foo));

        return result;
    }

    @RequestMapping("/check")
    public Result fooCheck(@RequestParam String no) {
        Result<Foo> result = new Result<>();
        if (Strings.isNullOrEmpty(no)) {
            ResultUtils.packFailedResult(result, "房间编号不能为空");
            return result;
        }
        Foo foo = getFoo(no);
        if (foo == null) {
            ResultUtils.packFailedResult(result, "该房间不存在");
            return result;
        }
//        // 不返回房间密码信息
//        Foo foo1 = new Foo();
//        BeanUtils.copyProperties(foo, foo1);
//        foo1.setPwd("UNKNOWN");
        result.setData(foo);
        ResultUtils.packSuccessfulResult(result);
        return result;
    }

    @RequestMapping("/join")
    public Result fooJoin(@RequestParam String no, String pwd, HttpSession session) {
        Result<String> result = new Result<>();
        Foo foo = getFoo(no);
        if (foo == null) {
            ResultUtils.packFailedResult(result, "非法加入");
            return result;
        }
        FooAuth authType = foo.getAuthType();
        FooMember fooMember;
        String uId = (String) session.getAttribute(Constant.SESSION_LOGIN_USER_KEY);
        switch (authType) {
            case PUBLIC:
                ResultUtils.packSuccessfulResult(result);
                result.setData("");
                return result;
            case DEFAULT:
                if (Strings.isNullOrEmpty(uId)) {
                    ResultUtils.packFailedResult(result, "房主要求用户登录后可以加入");
                    return result;
                }
                fooMember = new FooMember(uId, no);
                fooMember.setRole(MemberRole.MEMBER);
                fooMember.setJoinTime(format.format(new Date()));
                foo.getMembers().add(fooMember);
                redisTemplate.opsForValue().set(no, foo);
                return result;
            case PROTECTED:
                if (Strings.isNullOrEmpty(pwd) || !pwd.equals(foo.getPwd())) {
                    ResultUtils.packFailedResult(result, "房间密码不匹配");
                    return result;
                }
                fooMember = new FooMember(uId, no);
                fooMember.setRole(MemberRole.MEMBER);
                fooMember.setJoinTime(format.format(new Date()));
                foo.getMembers().add(fooMember);
                redisTemplate.opsForValue().set(no, foo);
                ResultUtils.packSuccessfulResult(result);
                return result;
            default:
                ResultUtils.packFailedResult(result, "房间类型非法");
                break;
        }
        return result;

    }

//    @MessageMapping("/greet")
//    @SendTo("/topic/notice")
//    public String joinChatRoom(String value) {
//        System.out.println(value);
//        return "NIHK";
//    }


    /**
     * 获取指定房间号的对象
     *
     * @param fooId 房间编号
     * @return 房间model
     */
    private static Foo getFoo(String fooId) {
        return redisTemplate.opsForValue().get(fooId);
    }

    /**
     * 查询是否存在指定房间号的房间
     *
     * @param fooId 房间编号
     * @return 存在为true否则false
     */
    private static boolean checkFooExist(String fooId) {
        return getFoo(fooId) != null;
    }


    /**
     * 获取不重复房间编号，最大尝试100次
     *
     * @return 房间编号
     */
    private static String getDiffFooId() {
        int i = 0;
        int maxTry = 100;
        while (i++ < maxTry) {
            String id = IdUtils.getFooId();
            if (!checkFooExist(id)) {
                return id;
            }
        }
        return "";
    }
}
